package com.personal.core.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * 文件操作工具类
 * description
 * @author cuibo
 */
public class FileUtil
{

    /**
     * 在本地地址创建文件
     * @param filePath 文件 地址
     * @param by 字节流
     * @return
     * @throws IOException
     */
    public static File createFile(String filePath, byte[] by) throws IOException
    {

        File prjfile = new File(filePath.replace("\\", "/").replace("//", "/"));
        if (!prjfile.exists())
        {
            File parent = prjfile.getParentFile();
            if (!parent.exists())
            {
                parent.mkdirs();
            }
            // 创建新文件
            prjfile.createNewFile();
        }
        writeByteToFile(by, prjfile);
        return prjfile;
    }

    public static byte[] readInputStream(InputStream in) throws IOException
    {
        if (in == null)
        {
            return null;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        writeStream(in, out);
        return out.toByteArray();
    }

    /**
     * 初始化本地文件
     */
    public static void createFile(String filePath, InputStream is) throws Exception
    {
        // 存储路径
        File saveFile = new File(filePath);

        if (!saveFile.exists())
        {
            // 返回文件流
            BufferedOutputStream sos = new BufferedOutputStream(new FileOutputStream(saveFile));

            // 构建缓存流
            BufferedInputStream fis = new BufferedInputStream(is);
            try
            {
                byte[] b = new byte[1024 * 1024];
                int i = 0;
                while ((i = fis.read(b)) > 0)
                {
                    sos.write(b, 0, i);
                }
                sos.flush();
            } catch (Exception e)
            {
                e.printStackTrace();
            } finally
            {
                release(sos);
                release(fis);
            }
        }
    }

    /**
     * 删除文件夹以及下面所有文件
     * @param directoryPath
     * @return
     */
    public static boolean deleteDir(File file)
    {
        if (file == null)
        {
            return false;
        }
        if (file.isDirectory())
        {
            String[] fileNames = file.list();
            for (String fileName : fileNames)
            {
                boolean success = FileUtil.deleteDir(new File(file, fileName));
                if (!success)
                {
                    return false;
                }
            }
        }
        return file.delete();
    }

    /**
     * 清除文件
     * @param file
     * @return
     */
    public static boolean deleteFiles(File file, boolean bDelDirectory)
    {
        if (!file.exists())
        {
            return true;
        }
        if (file.isFile())
        {
            // 文件
            return file.delete();
        } else
        {
            // 文件夹
            for (File f : file.listFiles())
            {
                if (f.isFile())
                {
                    // 删除文件
                    if (!f.delete())
                    {
                        return false;
                    }
                } else
                {
                    // 文件夹
                    if (!FileUtil.deleteFiles(f, true))
                    {
                        return false;
                    }
                }
            }

            // 删除文件夹
            if (bDelDirectory)
            {
                return file.delete();
            }

            return true;
        }
    }

    /**
     * 关闭输入流
     * @param rs 输入流
     *
     */
    public static void release(InputStream rs)
    {
        if (rs != null)
        {
            try
            {
                rs.close();
            } catch (Exception e)
            {
                rs = null;
                e.printStackTrace();
            }
        }

    }

    /**
     * 关闭输出流
     * @param rs 输出流
     *
     */
    public static void release(OutputStream rs)
    {
        if (rs != null)
        {
            try
            {
                rs.close();
            } catch (Exception e)
            {
                rs = null;
                e.printStackTrace();
            }
        }

    }

    /**
     * 将byte数组写入 文件
     * @param bts
     * @param file
     */
    public static void writeByteToFile(byte[] bts, File file)
    {
        BufferedOutputStream out = null;
        try
        {
            out = new BufferedOutputStream(new FileOutputStream(file));
            out.write(bts);
            out.flush();
        } catch (Exception e)
        {
            e.printStackTrace();
        } finally
        {
            release(out);
        }
    }

    /**
     * 将流写入指定路径文件
     * @param inputStream
     * @param filePath
     * @return
     * @throws IOException
     */
    public static boolean writeFile(byte[] by, String filePath) throws IOException
    {
        if (by == null || CoreUtil.isEmpty(filePath))
        {
            return false;
        }

        File file = new File(filePath.replace("\\", "/").replace("//", "/"));
        if (!file.exists())
        {
            File parent = file.getParentFile();
            if (!parent.exists())
            {
                // 新建文件夹
                if (!parent.mkdirs())
                {
                    return false;
                }
            }
            // 创建新文件
            if (!file.createNewFile())
            {
                return false;
            }
        }

        FileOutputStream outputStream = null;
        try
        {
            outputStream = new FileOutputStream(file);
            // 写入流
            return FileUtil.writeStream(by, outputStream);
        } finally
        {
            release(outputStream);
        }
    }

    /**
     * 将流写入指定路径文件
     * @param by
     * @param filePath
     * @param append
     * @return
     * @throws IOException
     */
    public static boolean writeFile(byte[] by, String filePath, boolean append) throws IOException
    {
        if (by == null || CoreUtil.isEmpty(filePath))
        {
            return false;
        }

        File file = new File(filePath.replace("\\", "/").replace("//", "/"));
        if (!file.exists())
        {
            File parent = file.getParentFile();
            if (!parent.exists())
            {
                // 新建文件夹
                if (!parent.mkdirs())
                {
                    return false;
                }
            }
            // 创建新文件
            if (!file.createNewFile())
            {
                return false;
            }
        }

        FileOutputStream outputStream = null;
        try
        {
            outputStream = new FileOutputStream(file, append);
            // 写入流
            return FileUtil.writeStream(by, outputStream);
        } finally
        {
            release(outputStream);
        }
    }

    /**
     * 将流写入指定路径文件
     * @param inputStream
     * @param filePath
     * @return
     * @throws IOException
     */
    public static boolean writeFile(InputStream inputStream, String filePath) throws IOException
    {
        if (inputStream == null || CoreUtil.isEmpty(filePath))
        {
            return false;
        }

        File file = new File(filePath.replace("\\", "/").replace("//", "/"));
        if (!file.exists())
        {
            File parent = file.getParentFile();
            if (!parent.exists())
            {
                // 新建文件夹
                if (!parent.mkdirs())
                {
                    return false;
                }
            }
            // 创建新文件
            if (!file.createNewFile())
            {
                return false;
            }
        }

        FileOutputStream outputStream = null;
        try
        {
            outputStream = new FileOutputStream(file);
            // 写入流
            return FileUtil.writeStream(inputStream, outputStream);
        } finally
        {
            release(outputStream);
            release(inputStream);
        }
    }

    public static boolean writeStream(byte[] by, OutputStream outputStream) throws IOException
    {
        if (by == null || outputStream == null)
        {
            return false;
        }

        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try
        {
            bos = new BufferedOutputStream(outputStream);

            bos.write(by, 0, by.length);
        } finally
        {
            release(bis);
            release(bos);
        }
        return true;
    }

    public static boolean writeStream(InputStream inputStream, OutputStream outputStream) throws IOException
    {
        if (inputStream == null || outputStream == null)
        {
            return false;
        }

        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try
        {
            bis = new BufferedInputStream(inputStream);
            bos = new BufferedOutputStream(outputStream);

            byte[] buffer = new byte[102400];
            int len;

            while ((len = bis.read(buffer)) > 0)
            {
                bos.write(buffer, 0, len);
            }
        } finally
        {
            FileUtil.release(bis);
            FileUtil.release(bos);
            FileUtil.release(inputStream);
            FileUtil.release(outputStream);
        }
        return true;
    }

    /**
     * 获取file下所有的文件
     * @param file
     * @param filter
     * @return
     */
    public static List<File> getAllFiles(File file, FileFilter filter)
    {
        if (!file.exists())
        {
            return null;
        }
        List<File> result = new ArrayList<File>();
        if (file.isFile())
        {
            if (filter == null)
            {
                result.add(file);
            } else
            {
                if (filter.accept(file))
                {
                    result.add(file);
                }
            }
            return result;
        } else
        {
            File[] files = file.listFiles(filter);
            if (files != null && files.length > 1)
            {
                List<File> singFiles = null;
                for (File file2 : files)
                {
                    singFiles = getAllFiles(file2, filter);
                    if (singFiles != null && singFiles.size() > 0)
                    {
                        result.addAll(singFiles);
                    }
                }
            }
            return result;
        }
    }

    /**
     * 处理部分浏览器上传附件名称问题
     * @param fileName
     * @return
     */
    public static String handleIEFileName(String fileName)
    {
        if (CoreUtil.isEmpty(fileName))
        {
            return fileName;
        }
        if (fileName.contains(File.separator))
        {
            fileName = fileName.substring(fileName.lastIndexOf(File.separator) + 1);
        }
        return fileName;
    }
    
    /**
     * 处理部分浏览器上传附件名称问题
     * @param filePath
     * @return
     */
    public static String handleFilePathName(String filePath)
    {
        if (CoreUtil.isEmpty(filePath))
        {
            return filePath;
        }
        StringUtil.replace(StringUtil.replace(StringUtil.replace(filePath, "//", File.separator), "\\", File.separator), "\\\\", File.separator);
        return filePath;
    }
    
    /**
     * 获取java.io.tmpdir
     * @return
     */
    public static String getJavaIoTmpDir()
    {
        return System.getProperty("java.io.tmpdir");
    }
    
    /**
     * 获取附件路径地址
     * @return
     */
    public static String getAttachFilePath()
    {
        return System.getProperty("filemanage-storepath");
    }

    /**
     * 是否是Excel文件
     * @param fileName
     * @return
     */
    public static boolean isExcel(String fileName)
    {
        if (CoreUtil.isEmpty(fileName))
        {
            return false;
        }
        fileName = fileName.toLowerCase();
        return fileName.endsWith(".xls") || fileName.endsWith(".xlsx") || fileName.endsWith(".xlsm");
    }
    
    /**
     * 是否是Word文件
     * @param fileName
     * @return
     */
    public static boolean isWord(String fileName)
    {
        if (CoreUtil.isEmpty(fileName))
        {
            return false;
        }
        fileName = fileName.toLowerCase();
        return fileName.endsWith(".doc") || fileName.endsWith(".docx");
    }
    
}
